package com.grsu.phonestation.web;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.grsu.phonestation.domain.Admin;
import com.grsu.phonestation.domain.Client;
import com.grsu.phonestation.domain.FreeService;
import com.grsu.phonestation.domain.InternetService;
import com.grsu.phonestation.domain.PhoneService;
import com.grsu.phonestation.domain.Service;
import com.grsu.phonestation.domain.Subscribe;
import com.grsu.phonestation.service.FreeServiceService;
import com.grsu.phonestation.service.InternetServiceService;
import com.grsu.phonestation.service.PhoneServiceService;
import com.grsu.phonestation.service.ServiceService;
import com.grsu.phonestation.service.SubscribeService;
import com.grsu.phonestation.web.info.InfoService;

@Controller
@RequestMapping("/services")
public class ServiceController {

	@Autowired
	@Qualifier("serviceServiceImpl")
	private ServiceService<Service> serviceService;

	@Autowired
	private InternetServiceService internetServiceService;

	@Autowired
	private PhoneServiceService phoneServiceService;

	@Autowired
	private FreeServiceService freeServiceService;

	@Autowired
	private SubscribeService subscribeService;

	@RequestMapping(value = { "/", " " }, method = { RequestMethod.GET })
	public ModelAndView listServices(HttpSession session, Model model) {

		ModelAndView mav = new ModelAndView();

		Object userObject = session.getAttribute("user");
		if (userObject != null) {

			if (userObject instanceof Client) {

				Client user = (Client) userObject;

				List<InfoService> infoServices = new ArrayList<InfoService>();

				preparationServices(user, infoServices);

				mav.addObject("user", user);
				mav.addObject("infoServices", infoServices);
				mav.setViewName("services");
			}
			if (userObject instanceof Admin) {

				Admin user = (Admin) userObject;

				List<Service> services = serviceService.listServices();
				List<InfoService> infoServices = new ArrayList<InfoService>();

				for (Service service : services) {
					infoServices.add(new InfoService(service));
				}

				mav.addObject("user", user);
				mav.addObject("infoServices", infoServices);
				mav.setViewName("admin.services");

			}
		} else {
			mav = new ModelAndView("redirect:/login");
			mav.setViewName("login");
		}

		return mav;
	}

	private void preparationServices(Client user, List<InfoService> infoServices) {

		List<Subscribe> subscribes = subscribeService
				.getSubscribeServiceClient(user);

		List<Service> services = serviceService.listServices();

		for (Service service : services) {

			boolean canSubscribe = false;

			for (Subscribe subscribe : subscribes) {
				if (service.equals(subscribe.getService())) {
					canSubscribe = true;
					break;
				}
			}

			infoServices.add(new InfoService(service, canSubscribe));
		}
	}

	@RequestMapping(value = "/subcribe/{id}", method = RequestMethod.GET)
	public ModelAndView subscribeOnService(@ModelAttribute Subscribe subscribe,
			@PathVariable("id") Integer serviceId, HttpSession session,
			Model model) {

		ModelAndView mav = new ModelAndView("redirect:/services/");

		Service service = serviceService.getServiceById(serviceId);

		Object userObject = session.getAttribute("user");

		if ((userObject != null) && (userObject instanceof Client)
				&& service != null) {

			Client user = (Client) userObject;

			Date date = new Date();

			subscribe.setUser(user);
			subscribe.setService(service);
			subscribe.setDateActivation(date);

			subscribeService.addSubscribe(subscribe);

			List<InfoService> infoServices = new ArrayList<InfoService>();

			preparationServices(user, infoServices);

			mav.addObject("user", user);
			mav.addObject("infoServices", infoServices);
		}

		mav.setViewName("services");

		return mav;
	}

	@RequestMapping(value = "/delete/{id}", method = RequestMethod.GET)
	public ModelAndView deliteService(@PathVariable("id") Integer serviceId,
			HttpSession session, Model model) {

		ModelAndView mav = new ModelAndView("redirect:/services");

		serviceService.removeService(serviceId);

		return mav;
	}

	@RequestMapping(value = "/edit", method = { RequestMethod.POST })
	public ModelAndView editService(@Valid @ModelAttribute Service service,
			Integer idService, Double price, HttpSession session, Model model) {

		ModelAndView mav = new ModelAndView("redirect:/services");

		Service objectService = serviceService.getServiceById(idService);

		if (objectService instanceof FreeService) {
			FreeService editService = (FreeService) objectService;

			editService.setNameService(service.getNameService());
			editService.setDescription(service.getDescription());

			serviceService.editService(editService);
		} else {
			if (objectService instanceof InternetService) {
				InternetService editService = (InternetService) objectService;

				editService.setNameService(service.getNameService());
				editService.setDescription(service.getDescription());
				editService.setPrice(price);

				serviceService.editService(editService);
			}
			else {
				if (objectService instanceof PhoneService) {
					PhoneService editService = (PhoneService) objectService;

					editService.setNameService(service.getNameService());
					editService.setDescription(service.getDescription());
					editService.setPrice(price);

					serviceService.editService(editService);
				}
			}
		}

		List<Service> services = serviceService.listServices();

		List<InfoService> infoServices = new ArrayList<InfoService>();

		for (Service addservice : services) {
			infoServices.add(new InfoService(addservice));
		}

		mav.addObject("infoServices", infoServices);
		return mav;
		
	}

	@RequestMapping(value = "/new", method = { RequestMethod.POST })
	public ModelAndView newService(Integer typeService,
			String nameService, String description, Double price,
			HttpSession session, Model model) {

		ModelAndView mav = new ModelAndView("redirect:/services");

		switch (typeService) {
		case 1:
			if (nameService != null && description != null && price != null) {

				InternetService service = new InternetService();
				service.setNameService(nameService);
				service.setDescription(description);
				service.setPrice(price);

				internetServiceService.addService(service);

			}
			break;
		case 2:
			if (nameService != null && description != null && price != null) {

				PhoneService service = new PhoneService();
				service.setNameService(nameService);
				service.setDescription(description);
				service.setPrice(price);

				phoneServiceService.addService(service);

			}
			break;
		case 3:
			if (nameService != null && description != null) {

				FreeService service = new FreeService();
				service.setNameService(nameService);
				service.setDescription(description);

				freeServiceService.addService(service);

			}
			break;
		default:
			break;
		}

		List<Service> services = serviceService.listServices();

		List<InfoService> infoServices = new ArrayList<InfoService>();

		for (Service service : services) {
			infoServices.add(new InfoService(service));
		}

		mav.addObject("infoServices", infoServices);
		return mav;
	}
}
